﻿using System;
using System.Linq;
using System.Reflection;
using PostSharp.Aspects;

namespace AopDemo
{
    //在程序编译完成之后，PostSharp会接管并执行Weaving（编织）。因为PostSharp是一个post compilerAOP 工具，因此它会在程序编译之后、执行之前修改程序。
    //[Serializable]：当使用PostSharp时，必须要确保在切面类上使用了[Serializable]特性，因为PostSharp需要实例化并序列化切面对象，为的是能够在编译后反序列化这些对象使用。
    //MethodInterceptionAspect：所有的方法拦截切面都必须继承这个类。
    //OnInvoke:故名思义，就是在拦截方法执行时会调用这个方法，其实准确讲，被拦截的方法会在这个方法里面执行。

    /// <summary>
    /// 方法拦截
    /// </summary>
    public class PostSharpMethodInterceptionAspectDemo
    {
        [MyInterceptorAspect]
        public static void Send(string msg)
        {
            Console.WriteLine("【微博客户端】正在发送消息：" + msg);
        }

        [Serializable]
        public class MyInterceptorAspect : MethodInterceptionAspect
        {
            public override void OnInvoke(MethodInterceptionArgs args)
            {
                Console.WriteLine("【拦截器：】，方法执行前拦截到的信息是：" + args.Arguments.First());//打印出拦截的方法第一个实参
                args.Proceed();//Proceed()方法表示继续执行拦截的方法
                Console.WriteLine("【拦截器：】，方法已在成功{0}执行", DateTime.Now);//被拦截方法执行完成之后执行
            }
        }
    }

    public class PostSharpMethodInterceptionAspectClient
    {

        public static void Run()
        {
            PostSharpMethodInterceptionAspectDemo.Send("PostSharpMethodInterceptionAspectClient  hello");
        }
    }
    /// <summary>
    /// 边界拦截
    /// </summary>
    public class PostSharpMethodBoundaryAspectDemo
    {
        [Serializable]
        public class MyBoundaryAspect : OnMethodBoundaryAspect
        {
            public override void OnEntry(MethodExecutionArgs args)
            {
                Console.WriteLine("方法{0}执行前", args.Method.Name);
            }

            public override void OnSuccess(MethodExecutionArgs args)
            {
                Console.WriteLine("方法{0}执行后", args.Method.Name);
            }
        }

        /// <summary>
        /// 根据球员的名字返回球员的球衣号码
        /// </summary>
        /// <param name="playerName"></param>
        /// <returns></returns>
        [MyBoundaryAspect]
        public static void Send2(string msg)
        {
            Console.WriteLine("【微博客户端】正在发送消息：" + msg);
        }

    }
    public class PostSharpMethodBoundaryAspectClient
    {

        public static void Run()
        {
            PostSharpMethodBoundaryAspectDemo.Send2("PostSharpMethodBoundaryAspectClient  hello");
        }
    }

    /// <summary>
    /// 属性拦截
    /// </summary>
    public class PostSharpLocationInterceptionAspectDemo
    {
        [Serializable]
        public class MyLocationAspect : LocationInterceptionAspect
        {
            public override void OnGetValue(LocationInterceptionArgs args)
            {
                Console.WriteLine("这条语句来自位置拦截的{0}方法", MethodBase.GetCurrentMethod());
                args.ProceedGetValue();
            }

            public override void OnSetValue(LocationInterceptionArgs args)
            {
                Console.WriteLine("这条语句来自位置拦截的{0}方法", MethodBase.GetCurrentMethod());
                args.ProceedSetValue();
            }
        }
        public class TestClass2
        {
            [MyLocationAspect]
            public string TestProperty
            {
                get;
                set;
            }
        }

    }

    public class PostSharpLocationInterceptionAspectClient
    {
        public static void Run()
        {
            var test2 = new PostSharpLocationInterceptionAspectDemo.TestClass2();
            test2.TestProperty = "位置拦截测试";
            Console.WriteLine(test2.TestProperty);
        }
    }
}
